package omg.DbHandling;

import com.mysql.jdbc.PreparedStatement;
import java.net.URI;
import java.net.URISyntaxException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import omg.Error.DBError;

public class DatabaseInt {

	private static DatabaseInt instance = null;

        private static final String DB_CONN_STRING = "jdbc:mysql://127.0.0.1:3306/omg";
        private static final String DRIVER_CLASS_NAME = "com.mysql.jdbc.Driver";
        private static final String USER_NAME = "omg";
        private static final String PASSWORD = "omg";
        private static final String TABLE_CONFIG = "configuration";

	/* SINGLETON PATTERN */
        private DatabaseInt() {}
	public static DatabaseInt getInstance() {
            if (null == DatabaseInt.instance)
                DatabaseInt.instance = new DatabaseInt();
            return DatabaseInt.instance;
	}

	/**
         * @return
         * @throws DBError 
	 */
	public URI getStoreLocation() throws DBError {
            try {
                return new URI(getEntryFromConfigurationTable("StoreLocation"));
            } catch (URISyntaxException ex) {
                Logger.getLogger(("Information")).log(Level.SEVERE, "StoreLocation string in configuration table is maleformed.", ex);
                throw new DBError("StoreLocation string in configuration table is maleformed. See log file.");
            }
	}

	/**
	 * 
	 * @return 
	 */
	public String getStringRepresentationPattern() throws DBError {
            return getEntryFromConfigurationTable("StringRepresentation");
        }


	/**
	 * 
	 * @param uri
	 * @return 
	 */
	public void setStoreLocaltion(java.net.URI uri) {
		throw new UnsupportedOperationException();
	}

	/**
	 * 
	 * @param pattern
	 * @return 
	 */
	public void setStringRepresentationPattern (String pattern) {
		throw new UnsupportedOperationException();
	}

	/**
	 * 
         * @return
         * @throws DBError
	 */
	public boolean isAutoPersist() throws DBError {
            Integer value = Integer.parseInt(getEntryFromConfigurationTable("AutoPersist"));
            if (1 == value)
                return true;
            else
                return false;
	}

	/**
	 * 
	 * @return 
	 */
	public void setAutoPersist() {
		throw new UnsupportedOperationException();
	}

	/**
	 * 
	 * @return 
	 */
	public void unsetAutoPersist() {
		throw new UnsupportedOperationException();
	}

        /**
         *
         * @param String field
         * @return value
         * @throws DBError
         */
        public String getConfigValue(String field) throws DBError {
            try {
                Connection cn = DatabaseInt.getConnection();
                Statement st = cn.createStatement();
                ResultSet rs = st.executeQuery("SELECT `value` FROM `" + TABLE_CONFIG + "` WHERE `key` = '" + field +  "';");
                rs.last();
                if (1 != rs.getRow() )
                    throw new DBError("You are tyring to get the config entry which is appears to be not existsing. Check the spelling or create it first.");
                return rs.getString("value");
            } catch (SQLException ex) {
                Logger.getLogger(("Information")).log(Level.SEVERE, "Couldn't execute sql statement to access configuration table.", ex);
                throw new DBError("Configuration table " + TABLE_CONFIG + " is maleformed. Couldn't access.");
            }
        }

        /**
         *
         * @param field
         * @param value
         * @throws DBError
         */
        public int setConfigValue(String field, String value) throws DBError {
            try {
                Connection cn = DatabaseInt.getConnection();
                java.sql.PreparedStatement query = cn.prepareStatement("UPDATE " + TABLE_CONFIG + " SET `value` = ? WHERE `key` = ?;");
                query.setString(1, value);
                query.setString(2, field);
                return query.executeUpdate();
            } catch (SQLException ex) {
                Logger.getLogger(("Information")).log(Level.SEVERE, "Couldn't execute sql statement to access configuration table.", ex);
                throw new DBError("Configuration table " + TABLE_CONFIG + " is maleformed. Couldn't access.");
            }
        }

        private String getEntryFromConfigurationTable (String field) throws DBError {
            try {
                Connection cn = DatabaseInt.getConnection();
                Statement st = cn.createStatement();
                ResultSet rs = st.executeQuery("SELECT `value` FROM `" + TABLE_CONFIG + "` WHERE `key` = '" + field +  "';");
                rs.last();
                if (1 != rs.getRow() )
                    throw new DBError("Configuration table " + TABLE_CONFIG + " is maleformed. Statement produced empty result.");
                return rs.getString("value");
            } catch (SQLException ex) {
                Logger.getLogger(("Information")).log(Level.SEVERE, "Couldn't execute sql statement to access configuration table.", ex);
                throw new DBError("Configuration table " + TABLE_CONFIG + " is maleformed. Couldn't access.");
            }
        }

        private static Connection getConnection() throws DBError {
            try {
                Logger.getLogger("Periphery").addHandler(new FileHandler("lick.log"));
            } catch (Exception ex) {}
            try {
                Class.forName(DRIVER_CLASS_NAME).newInstance();
                return DriverManager.getConnection(DB_CONN_STRING, USER_NAME, PASSWORD);
            } catch (SQLException ex) {
                Logger.getLogger("Periphery").log(Level.SEVERE, "MySQL Exception raised on creating connection.", ex);
                throw new DBError("Connecting to MySQL server failed.", ex);
            } catch (InstantiationException ex) {
                Logger.getLogger("Periphery").log(Level.SEVERE, "Couldn't established MySQL connection.", ex);
                throw new DBError("Connecting to MySQL server failed.", ex);
            } catch (IllegalAccessException ex) {
                Logger.getLogger("Periphery").log(Level.SEVERE, "No access rights to MySQL.", ex);
                throw new DBError("Connecting to MySQL server failed.", ex);
            } catch (ClassNotFoundException ex) {
                Logger.getLogger("Periphery").log(Level.SEVERE, "The MySQL drivers are not present.", ex);
                throw new DBError("Connecting to MySQL server failed.", ex);
            }
      }
}